import React, { memo, useState, useEffect, useRef, useCallback } from 'react';
import { useDispatch, useSelector, shallowEqual } from 'react-redux';
import { NavLink } from "react-router-dom"

// 引入 antd 组件 
import { Slider, message } from 'antd';
import { getSizeImage, formatDate, getPlaySong } from '@/utils/format-utils';
import { getSongDetailAction, changeSequenceAction, changeCurrentIndexAndSongAction, changeCurrentLyricIndexAction } from '../store/actionCreators'

import {
  PlaybarWrapper,
  Control,
  PlayInfo,
  Operator
} from './style';
export default memo(function DDDGAppPlayerBar() {
  const [currentTime, setCurrentTime] = useState(0); // 实时的播放进度
  const [progress, setProgress] = useState(0);  // 进度条的百分比
  const [isChanging, setIsChanging] = useState(false); // 进度条当前是否正在发生改变
  const [isPlaying, setIsPlaying] = useState(false); // 播放/暂停

  // redux hook
  const {
    currentSong,// 当前播放的 歌曲
    sequence, // 循环 还是  单曲循环 还是 随机
    lyricList,
    currentLyricIndex
  } = useSelector(state => ({
    currentSong: state.getIn(["player", "currentSong"]),
    sequence: state.getIn(["player", "sequence"]),
    lyricList: state.getIn(["player", "lyricList"]),
    currentLyricIndex: state.getIn(["player", "currentLyricIndex"])
  }), shallowEqual);
  const dispatch = useDispatch()
  useEffect(() => {
    dispatch(getSongDetailAction(167876))
  }, [dispatch])

  // other hooks
  const audioRef = useRef()

  useEffect(() => {
    audioRef.current.src = getPlaySong(currentSong.id);
    audioRef.current.volume = 0.2   //控制音量
    console.dir(audioRef.current);
    audioRef.current.play().then(res => {
      setIsPlaying(true);
    }).catch(err => {
      setIsPlaying(false);
    });
  }, [currentSong]);
  // other handle
  const picUrl = (currentSong.al && currentSong.al.picUrl) || ""
  const singerName = (currentSong.ar && currentSong.ar[0].name) || "未知歌手"
  const duration = currentSong.dt || 0;
  const showDuration = formatDate(duration, "mm:ss"); // 总时长
  const showCurrentTime = formatDate(currentTime, "mm:ss"); // 实时播放进度


  // handle function
  // isPlaying 发生改变的时候 才会执行这个
  const playMusic = useCallback(() => {
    isPlaying ? audioRef.current.pause() : audioRef.current.play();
    setIsPlaying(!isPlaying);
  }, [isPlaying]);

  //  播放进度更新
  const timeUpdate = (e) => {
    const currentTime = e.target.currentTime;  // 这里返回的是 秒
    // console.log(currentTime);

    if (!isChanging) {
      setCurrentTime(currentTime * 1000);
      setProgress(currentTime * 1000 / duration * 100);
    }

    // 获取歌词
    let i = 0;
    for (; i < lyricList.length; i++) {
      let lyricItem = lyricList[i];
      if (currentTime * 1000 < lyricItem.time) {
        break;
      }
    }
    // 别忘了 剪掉1 ，因为 实时的进度还没到这个地方

    if (currentLyricIndex !== i - 1) {
      dispatch(changeCurrentLyricIndexAction(i - 1));
      const content = lyricList[i - 1] && lyricList[i - 1].content
      message.open({
        key: "lyric", // key 的目的是 让页面始终出现一个 
        content: content,
        duration: 0,
        className: "lyric-class"
      })
    }
  }

  // 当把一个回调函数传入子组件的时候，尽量用 useCallback 包裹
  const sliderChange = useCallback((value) => {
    // 鼠标 放在进度条的时候，不能让 timeUpdate 事件改变 进度、时间
    setIsChanging(true);
    const currentTime = value / 100 * duration; // 毫秒
    setCurrentTime(currentTime);
    setProgress(value);
  }, [duration]);

  // 鼠标抬起的时候
  const sliderAfterChange = useCallback((value) => {
    const currentTime = value / 100 * duration / 1000;
    audioRef.current.currentTime = currentTime;
    setCurrentTime(currentTime * 1000);
    setIsChanging(false);

    if (!isPlaying) {
      playMusic()
    }
  }, [duration, isPlaying, playMusic]);


  //  歌曲播放顺序改变
  const changeSequence = () => {
    let currentSequence = sequence + 1;
    if (currentSequence > 2) {
      currentSequence = 0;
    }
    dispatch(changeSequenceAction(currentSequence));
  }

  //  歌曲 自动 播放 结束
  const handleMusicEnded = () => {
    if (sequence === 2) { // 单曲循环
      audioRef.current.currentTime = 0;
      audioRef.current.play();
    } else {
      dispatch(changeCurrentIndexAndSongAction(1));
    }
  }

  //  点击 上一首 或者下一首
  const changeMusic = (tag) => {
    dispatch(changeCurrentIndexAndSongAction(tag));
  }
  return (
    <PlaybarWrapper className="sprite_player">
      <div className="content wrap-v2">
        <Control isPlaying={isPlaying}>
          <button className="sprite_player prev"
            onClick={e => changeMusic(-1)}></button>
          <button className="sprite_player play" onClick={e => playMusic()}></button>
          <button className="sprite_player next"
            onClick={e => changeMusic(1)}></button>
        </Control>
        <PlayInfo>
          <div className="image">
            <NavLink to="/discover/player">
              <img src={getSizeImage(picUrl, 35)} alt="" />
            </NavLink>
          </div>
          <div className="info">
            <div className="song">
              <span className="song-name">{currentSong.name}</span>
              <a href="#/" className="singer-name">{singerName}</a>
            </div>
            <div className="progress">
              <Slider defaultValue={30} value={progress} onChange={sliderChange} onAfterChange={sliderAfterChange} />
              <div className="time">
                <span className="now-time">{showCurrentTime}</span>
                <span className="divider">/</span>
                <span className="duration">{showDuration}</span>
              </div>
            </div>
          </div>
        </PlayInfo>
        <Operator sequence={sequence}>
          <div className="left">
            <button className="sprite_player btn favor"></button>
            <button className="sprite_player btn share"></button>
          </div>
          <div className="right sprite_player">
            <button className="sprite_player btn volume"></button>
            <button className="sprite_player btn loop" onClick={e => changeSequence()}></button>
            <button className="sprite_player btn playlist"></button>
          </div>
        </Operator>
      </div>
      <audio ref={audioRef} onTimeUpdate={e => timeUpdate(e)} onEnded={e => handleMusicEnded()} />
    </PlaybarWrapper>
  )
})
